/* 
 * Copyright 2010-2011 Johannes Tuikkala <johannes.tuikkala@itmill.com>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.vaadin.webcamforvaadin;

import com.github.wolfie.refresher.Refresher;
import com.vaadin.Application;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.terminal.StreamResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Slider;
import com.vaadin.ui.Slider.ValueOutOfBoundsException;
import com.vaadin.ui.Window;

public class WebcamApplication extends Application implements WebCamListener {
	private static final long serialVersionUID = -6356915058067157554L;
	private WebCamForVaadin webcam;
	private Embedded image;
	private Window mainWindow;
	private Label info = new Label("", Label.CONTENT_XHTML);
	private CheckBox autoCapture;
	private HorizontalLayout mainLayout;
	private Slider slider = new Slider();
	private Button capture = new Button("Capture");
	private Refresher refresher = new Refresher();

	@Override
	public void init() {
		refresher.setRefreshInterval(1000);
		mainWindow = new Window("WebcamApplication");
		setMainWindow(mainWindow);
		mainWindow.addComponent(refresher);
		mainWindow.addComponent(info);
		mainLayout = new HorizontalLayout();
		mainLayout.setSpacing(true);
		HorizontalLayout lo2 = new HorizontalLayout();
		lo2.setSpacing(true);
		lo2.addComponent(getSizeSelect());
		mainWindow.addComponent(mainLayout);
		mainWindow.addComponent(lo2);
		webcam = new WebCamForVaadin(this);
		mainWindow
				.addComponent(new Label(
						"<small>Use the camera icon below to capture picture! Currently the server side cupturing is not possible..<br /></small>",
						Label.CONTENT_XHTML));
		mainWindow.addComponent(webcam);
		image = new Embedded("Image from webcam", null);
		mainWindow.addComponent(image);

		// mainLayout.addComponent(getSlider());
		// mainLayout.addComponent(getSwitch());
		// mainLayout.addComponent(getButton());
	}

	private Component getSizeSelect() {
		final NativeSelect ns = new NativeSelect();
		ns.addItem("160x120");
		ns.addItem("320x240");
		ns.addItem("400x400");
		ns.addItem("640x480");
		ns.setImmediate(true);
		ns.setNullSelectionAllowed(false);
		ns.select("640x480");
		ns.addListener(new Property.ValueChangeListener() {
			private static final long serialVersionUID = 1042190159578986847L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				int width = Integer.parseInt(ns.getValue().toString()
						.split("x")[0]);
				int height = Integer.parseInt(ns.getValue().toString()
						.split("x")[1]);
				webcam.setWebCamWidthAndHeight(width, height);
			}
		});
		return ns;
	}

	@SuppressWarnings("unused")
	private Component getButton() {
		capture.addListener(new Button.ClickListener() {
			private static final long serialVersionUID = 5792589179795292798L;

			@Override
			public void buttonClick(ClickEvent event) {
				webcam.capture();
			}
		});
		capture.setEnabled(false);
		return capture;
	}

	public Slider getSlider() {
		slider = new Slider("Select delay (ms) between frames");
		slider.setMin(0);
		slider.setMax(5000);
		slider.setWidth("190px");
		slider.setImmediate(true);
		slider.setEnabled(false);
		try {
			slider.setValue(1000);
		} catch (ValueOutOfBoundsException e) {
			e.printStackTrace();
		}
		slider.addListener(new ValueChangeListener() {
			private static final long serialVersionUID = -4663279145664160160L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				webcam.setFrameDelay((int) Double.parseDouble(slider.getValue()
						.toString()));
			}
		});
		return slider;
	}

	/**
	 * Checkbox for hiding the auto capture
	 * 
	 * @return
	 */
	public CheckBox getCheckBox() {
		autoCapture = new CheckBox("Auto capturing");
		autoCapture.setImmediate(true);
		autoCapture.setValue(false);
		autoCapture.addListener(new Button.ClickListener() {
			private static final long serialVersionUID = -7254027776219296529L;

			public void buttonClick(ClickEvent event) {
				if ((Boolean) autoCapture.getValue()) {
					webcam.setFrameDelay((int) Double.parseDouble(slider
							.getValue().toString()));
				} else {
					webcam.setFrameDelay(-1);
				}
			}
		});
		return autoCapture;
	}

	@Override
	public void onImageReady() {
		info.setValue("");
		StreamResource picture = webcam.getPicture();
		picture.setMIMEType("image/jpeg");
		image.setImmediate(true);
		image.setMimeType("image/jpeg");
		image.setSource(picture);
		mainWindow.requestRepaint();
	}

	@Override
	public void onError(String errorMsg) {
		info.setValue("<strong>" + errorMsg + "</srong>");
	}
}
